package org.putrpctorest.expression;

import java.util.Map;

import org.putrpctorest.PutRpcToRestError;

public class MethodCall extends AbstractExpression {
	

	public MethodCall(String id) {
		super(id);
	}
	
	public MethodCall(MethodCall methodCall) {
		super(methodCall.getId());
		this.targetObject = methodCall.getTargetObject();
		this.javaMethod = methodCall.getJavaMethod();
		this.paramCorrespondence = methodCall.paramCorrespondence;
	}

	private Object targetObject;

	private java.lang.reflect.Method javaMethod;

	private String[] paramCorrespondence;

	public Object getTargetObject() {
		return targetObject;
	}

	public void setTargetObject(Object targetObject) {
		this.targetObject = targetObject;
	}

	public java.lang.reflect.Method getJavaMethod() {
		return javaMethod;
	}

	public void setJavaMethod(java.lang.reflect.Method javaMethod) {
		this.javaMethod = javaMethod;
	}

	public String[] getParamCorrespondence() {
		return paramCorrespondence;
	}

	public void setParamCorrespondence(String[] paramCorrespondence) {
		this.paramCorrespondence = paramCorrespondence;
	}

	@Override
	public ExpressionResult route(Map<String, Object> params)
			throws Exception {
//		verifyParameters(params);
		return callJavaMethod(params);
	}

	private ExpressionResult callJavaMethod(Map<String, Object> params)
			throws Exception {
		Object[] javaParams = new Object[paramCorrespondence.length];

		for (int i = 0; i < paramCorrespondence.length; i++) {
			javaParams[i] = params.get(paramCorrespondence[i]);
		}

		ExpressionResult routerResult = new ExpressionResult(javaMethod.invoke(
				targetObject, javaParams));

		return routerResult;
	}

	private void verifyParameters(Map<String, Object> params) {
		if (params.size() != paramCorrespondence.length) {
			throw new PutRpcToRestError("Error in parameter correspondence!");
		}
	}

	@Override
	public String getType() {
		return "method-call";
	}

}
